package com.mall.b2c.domain.goods;

import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.persistence.PreRemove;

import net.sf.json.JSONObject;

import org.hibernate.search.annotations.ContainedIn;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.mall.common.domain.BaseEntity;
import org.springframework.util.CollectionUtils;

/**
 * 商品分类
 */
@Entity
@Table(name="b2c_goods_category")
@JsonIgnoreProperties(ignoreUnknown=true) 
public class GoodsCategoryDomain extends BaseEntity {
	private static final long serialVersionUID = -9062984894020411117L;

	@Field(index = Index.UN_TOKENIZED, name = "code")
	private String code;//编号
	@Field(index = Index.UN_TOKENIZED, name = "name")
	private String name;//名称
	private String pyName;//拼音
	private String note;//备注
	private String keyword;// 搜索关键字
	private Integer treeLevel;//层级
	private Boolean hasChild;//是否有子分类
	private Boolean recommend;//是否推荐
	private Boolean showInNav;// 是否前台可见
	private Integer priority;// 排序
	private String alias;//别名，目前用于erp同步

	@JsonIgnore private GoodsCategoryDomain parent;//父分类
	@JsonIgnore private Set<GoodsCategoryDomain> children;
	@JsonIgnore @ContainedIn private Set<GoodsDomain> goodses;


	@PreRemove
	public void preRemove(){
		if(!CollectionUtils.isEmpty(goodses)){
			for(GoodsDomain goods : goodses){
				goods.setGoodsCategory(null);
			}
		}
	}

	@Transient
	@Field(index = Index.UN_TOKENIZED, name = "parentName")
	public String getParentName(){
		if(parent == null){
			return null;
		}
		return parent.getName();
	}

	@Transient
	@Field(index = Index.UN_TOKENIZED, name = "topCateName")
	public String getTopCateName(){
		if(parent == null){
			return null;
		}
		GoodsCategoryDomain top = parent.getParent();
		if(top == null){
			return  null;
		}
		return top.getName();
	}

	@Transient
	@Field(index = Index.UN_TOKENIZED, name = "parentCode")
	public String getParentCode(){
		if(parent == null){
			return null;
		}
		return parent.getCode();
	}

	@Transient
	public String getPath() {
		return "/list-cat-" + this.getId() + ".jhtml";
	}

	@Transient
	public JSONObject getJSONObject(){
		JSONObject obj = new JSONObject();
		obj.put("id", this.getId());
		obj.put("pid", this.getParentId());
		obj.put("text", this.getName());
		return obj;
	}
	
	@Transient
	public Long getParentId() {
		GoodsCategoryDomain parent = getParent();
		if (parent != null) {
			return parent.getId();
		} else {
			return null;
		}
	}
	
	@PrePersist
	public void prePersist() {
		if(this.treeLevel == null) {
			if(this.parent == null) {
				this.setTreeLevel(0);
			} else {
				Integer parentTreeLevel = this.parent.getTreeLevel();
				this.setTreeLevel(parentTreeLevel != null ? parentTreeLevel + 1 : 1);
			}
		}
		if(this.showInNav == null) {
			this.setShowInNav(true);
		}
		if(this.getHasChild() == null){
			this.setHasChild(true);
		}
	}
	
	@PreUpdate
	public void preUpdate() {
		if(this.showInNav == null) {
			this.setShowInNav(true);
		}
		if(this.getHasChild() == null) {
			this.setHasChild(true);
		}
	}
	
	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPyName() {
		return pyName;
	}

	public void setPyName(String pyName) {
		this.pyName = pyName;
	}

	public String getNote() {
		return note;
	}

	public void setNote(String note) {
		this.note = note;
	}

	public String getKeyword() {
		return keyword;
	}

	public void setKeyword(String keyword) {
		this.keyword = keyword;
	}

	public Integer getTreeLevel() {
		return treeLevel;
	}

	public void setTreeLevel(Integer treeLevel) {
		this.treeLevel = treeLevel;
	}

	public Boolean getHasChild() {
		return hasChild;
	}

	public void setHasChild(Boolean hasChild) {
		this.hasChild = hasChild;
	}

	public Boolean getShowInNav() {
		return showInNav;
	}

	public void setShowInNav(Boolean showInNav) {
		this.showInNav = showInNav;
	}

	public Boolean getRecommend() {
		return recommend;
	}

	public void setRecommend(Boolean recommend) {
		this.recommend = recommend;
	}

	public Integer getPriority() {
		return priority;
	}

	public void setPriority(Integer priority) {
		this.priority = priority;
	}

	@ManyToOne(fetch = FetchType.LAZY, optional=true)
	@JoinColumn(name="parent_id")
	public GoodsCategoryDomain getParent() {
		return parent;
	}

	public void setParent(GoodsCategoryDomain parent) {
		this.parent = parent;
	}

	@OneToMany(fetch = FetchType.LAZY, mappedBy = "parent", cascade={CascadeType.REMOVE})
	@OrderBy(value="priority DESC")
	public Set<GoodsCategoryDomain> getChildren() {
		return children;
	}

	public void setChildren(Set<GoodsCategoryDomain> children) {
		this.children = children;
	}

	@OneToMany(fetch=FetchType.LAZY, mappedBy="goodsCategory")
	public Set<GoodsDomain> getGoodses() {
		return goodses;
	}

	public void setGoodses(Set<GoodsDomain> goodses) {
		this.goodses = goodses;
	}

	public String getAlias() {
		return alias;
	}

	public void setAlias(String alias) {
		this.alias = alias;
	}

}
